package org.korifey.ffbdd.samples.logic;

import java.util.Map;

public class Operation implements Expression {
	
	enum TYPE {
		AND ("&&"),
		OR ("||"),
		IMPL ("=>"),
		XOR ("^^"),
		EQ ("=="),
		NEQ ("!="),
		NEG("!!");
		
		private String lexem;
		private TYPE(String symbols) {
			this.lexem = symbols;
		}
		
		
		
		public String getLexem() {
			return lexem;
		}



		public static TYPE getType(String lexem) {
			for (TYPE t: TYPE.values()) {
				if (t.lexem.equals(lexem)) return t;
			}
			return null;
		}
		
		public static String[] getLexems() {
			String[] res = new String[values().length];
			for (int i=0; i<res.length; i++) res[i] = values()[i].getLexem();
			return res;
		}
		
	}
	
	protected Expression left;
	protected Expression right;
	protected TYPE type;
	
	public Operation(Expression left, Expression right, TYPE type) {
		super();
		this.left = left;
		this.right = right;
		this.type = type;
	}
	
	public boolean eval(Map<String, Boolean> env) {
		if (right == null) return ! left.eval(env);
		boolean l = left.eval(env);
		boolean r = right.eval(env);
		switch (type) {
		case AND: return l && r;
		case OR: return l || r;
		case IMPL: return (!l) || r;
		case XOR: return l ^ r;
		case EQ: return l == r;
		case NEQ: return l != r;
		default: throw new RuntimeException("Evaluation error: unsupported binary operation: "+type);
		}
	}
	
	public String toString() {
		if (right == null) {
			return TYPE.NEG.getLexem() + left.toString();
		} else {
			return "(" + left.toString() + type.getLexem() + right.toString() + ")";
		}
	}
	
	
	
}
